//
//  MyWorldLayer.m
//  FontAnimation
//
//  Created by etrump on 12/15/15.
//  Copyright © 2015 sky. All rights reserved.
//

#import <CoreFoundation/CFString.h>
#import <CoreText/CoreText.h>
#import "MyWorldLayer.h"

@interface MyWorldLayer ()

@property(strong, nonatomic) CAShapeLayer*  pathLayer;
@property(strong, nonatomic) CALayer*       penLayer;

@end


@implementation MyWorldLayer

-(instancetype) init
{
    self = [super init];
    if( self )
    {
        self.pathLayer = nil;
        self.penLayer  = nil;
    }
    
    return self;
}

+ (void) createAnimation : (NSString*)str font:(UIFont*)font rect:(CGRect)rect view:(UIView*)view color:(UIColor*)color;
{
    MyWorldLayer* instance = [[MyWorldLayer alloc] init];
    CGRect frame = rect;
    frame.origin.y = 0;
    frame.size.height = rect.size.height / 2;
    instance.frame = frame;
    instance.backgroundColor = [UIColor grayColor].CGColor;
    
    [view.layer addSublayer:instance];
    
    if( nil != instance.pathLayer )
    {
        [instance.pathLayer removeFromSuperlayer];
        [instance.penLayer removeFromSuperlayer];
        instance.pathLayer = nil;
        instance.penLayer = nil;
    }
    
    CGMutablePathRef paths = CGPathCreateMutable();
    CFStringRef fontName = (__bridge CFStringRef)font.fontName;
    CGFloat fontSize = font.pointSize;
    CTFontRef fontRef = CTFontCreateWithName(fontName, fontSize, NULL);
    NSMutableDictionary *nsdic = [[NSMutableDictionary alloc] init];
    CFMutableDictionaryRef dic = (__bridge CFMutableDictionaryRef)nsdic;
    CFDictionaryAddValue(dic, kCTFontAttributeName, fontRef);
    CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, (__bridge CFStringRef)str, dic);
    CTLineRef line = CTLineCreateWithAttributedString(attrString);
    CFArrayRef runA =  CTLineGetGlyphRuns(line);
    
    
    for( NSInteger runIndex=0; runIndex < CFArrayGetCount(runA); runIndex++ )
    {
        CTRunRef runb = (CTRunRef)CFArrayGetValueAtIndex(runA, runIndex);
        CTFontRef runFontS = CFDictionaryGetValue(CTRunGetAttributes(runb), kCTFontAttributeName);
        CGPoint oldPosition = CGPointZero;
        CGGlyph oldGlyph = 0;
        CGFloat width = instance.frame.size.width;
        CGFloat temp = 0;
        CGFloat offset = 0.0;
        
        for( NSInteger i=0; i < CTRunGetGlyphCount(runb); i++ )
        {
            CFRange range = CFRangeMake(i, 1);
            CGGlyph glyph = 0;
            CGPoint position = CGPointZero;
            
            CTRunGetGlyphs(runb, range, &glyph);
            CTRunGetPositions(runb, range, &position);
            
            CGFloat temp3 = position.x;
            NSInteger temp2 = (NSInteger)(temp3 / width);
            NSInteger temp1 = (NSInteger)(oldPosition.x / width);
            
            if( temp2 > temp1 )
            {
                temp = temp2;
                offset = position.x - (temp * width);
            }
            
            CGPathRef path = CTFontCreatePathForGlyph(runFontS, glyph, NULL);
            CGFloat x = position.x - temp * width - offset;
            CGFloat y = position.y - temp * 80 ;
            CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
            CGPathAddPath(paths, &transform, path);
            
            if( i > 0 )
            {
                oldGlyph = glyph;
                oldPosition = position;
            }
        }
        
    }
    
    UIBezierPath* bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:CGPointZero];
    [bezierPath appendPath:[UIBezierPath bezierPathWithCGPath:paths]];
    
    instance.pathLayer = [CAShapeLayer layer];
    instance.pathLayer.frame = CGRectMake(0, instance.frame.size.height - 50, instance.frame.size.width, instance.frame.size.height);
    instance.geometryFlipped = YES;
    instance.pathLayer.path = bezierPath.CGPath;
    instance.pathLayer.strokeColor = color.CGColor;
    instance.pathLayer.fillColor = NULL;
    instance.pathLayer.lineWidth = 3;
    instance.pathLayer.lineJoin = kCALineJoinBevel;
    
    UIImage *penImg = [UIImage imageNamed:@"pen.png"];
    CALayer *penLayer = [CALayer layer];
    penLayer.contents = (__bridge id _Nullable)(penImg.CGImage);
    penLayer.anchorPoint = CGPointZero;
    penLayer.frame = CGRectMake(0, 0, penImg.size.width, penImg.size.height);
    [instance.pathLayer addSublayer:penLayer];
    instance.penLayer = penLayer;
    
    [instance.pathLayer removeAllAnimations];
    [instance.penLayer removeAllAnimations];
    instance.penLayer.hidden = NO;
    
    CABasicAnimation* pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = 4.0;
    pathAnimation.fromValue = @0.0;
    pathAnimation.toValue = @1.0;
    [instance.pathLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
    [instance addSublayer:instance.pathLayer];
    
    CAKeyframeAnimation* penAniamtion = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    penAniamtion.duration = 4.0;
    penAniamtion.path = instance.pathLayer.path;
    penAniamtion.calculationMode = kCAAnimationPaced;
    penAniamtion.delegate = instance;
    [instance.penLayer addAnimation:penAniamtion forKey:@"position"];
    
}


-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    NSString* s = @"hhh";
    if( [anim isKindOfClass:[CAKeyframeAnimation class]] )
    {
        CAKeyframeAnimation* tmp = (CAKeyframeAnimation*)anim;
        s = tmp.keyPath;
    }
    
    self.penLayer.hidden = YES;
}

@end
